#include "communication.h"
#include "tools.h"
#include <QDebug>

bool readN(SocketBuf* socketBuf, unsigned char dat[], int n)
{
    if (socketBuf->size() < n)
    {
        return false;
    }
    for (int i = 0; i < n; ++i)
    {
        dat[i] = socketBuf->read();
    }
    if (check(dat, n - 1) != dat[n - 1])
    {
        return false;
    }
    for (int i = 0; i < n - 3; ++i)
    {
        dat[i] = dat[i + 3];
    }
    return true;
}

QByteArray formatSendData(CommunicationCommand command, unsigned char dat[], int n)
{
    unsigned char buf[128];
    buf[0] = 0xEF;
    buf[1] = 0xB0;
    buf[2] = command;
    for (int i = 0; i < n; ++i)
    {
        buf[3 + i] = dat[i];
    }
    buf[3 + n] = check(buf, 3 + n);
    QByteArray res(reinterpret_cast<const char*>(buf), 3 + n + 1);
    return res;
}

CommunicationCommand formatReadData(SocketBuf* socketBuf, unsigned char dat[])
{
    CommunicationCommand command = static_cast<CommunicationCommand>(socketBuf->moveToHead());
    bool ok;
    switch (command)
    {
    case NONE:
        command = NONE;
        break;
    case GOODS_SIZE:
        ok = readN(socketBuf, dat, 6);
        break;
    case FREQUSED_GOODS_SIZE:
        ok = readN(socketBuf, dat, 6);
        break;
    case GOODS_INFORMATION:
        ok = readN(socketBuf, dat, 22);
        break;
    case FREQUSED_GOODS_INFORMATION:
        ok = readN(socketBuf, dat, 8);
        break;
    case SHOW_INFORMATION:
        ok = readN(socketBuf, dat, 68);
        break;
    case REVER_ROW:
        ok = readN(socketBuf, dat, 6);
        break;
    case SPEECH_INFORMATION:
    {
        if (socketBuf->size() < 5)
        {
            command = NONE;
            break;
        }
        char numBuf[2];
        numBuf[0] = socketBuf->peek(4);
        numBuf[1] = socketBuf->peek(3);
        short n = *reinterpret_cast<short*>(numBuf);
        ok = readN(socketBuf, dat, 5 + n + 1);
    } break;
    case FREQUSED_GOODS_OK:
        ok = readN(socketBuf, dat, 6);
        break;
    case REMOVE_GOODS_OK:
        ok = readN(socketBuf, dat, 6);
        break;
    case REMOVE_FREQUSED_GODOS_OK:
        ok = readN(socketBuf, dat, 6);
        break;
    case TRANSACTION_RECORD:
        ok = readN(socketBuf, dat, 28);
        break;
    case CLEAR_AMOUNT:
        ok = readN(socketBuf, dat, 4);
        break;
    default:
        socketBuf->read();
        ok = false;
        break;
    }
    if (!ok)
    {
        command = NONE;
    }
    return command;
}
